package com.Endurancer.manager.service.impl;


import com.Endurancer.common.core.domain.AjaxResult;
import com.Endurancer.manager.service.IMsmService;
import com.Endurancer.manager.utils.RandomUtils;
import com.alibaba.fastjson2.JSON;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;


@Service
public class MsmServiceImpl implements IMsmService {

    private static final Logger logger = LoggerFactory.getLogger(MsmServiceImpl.class);
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    private static final Pattern PHONE_PATTERN = Pattern.compile("^[1]\\d{10}$");

    @Value("${aliyun.sms.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.sms.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.sms.signName}")
    private String signName;

    @Value("${aliyun.sms.templateCode.login}")
    private String templateCodeLogin;

    @Value("${aliyun.sms.templateCode.register}")
    private String templateCodeRegister;

    @Value("${aliyun.sms.templateCode.resetPassword}")
    private String templateCodeResetPassword;

    @Value("${aliyun.sms.templateCode.changePhone}")
    private String templateCodeChangePhone;

    public AjaxResult sendMsm(String phone, String type) {
        // 从redis获取验证码，如果获取到直接返回
        String code = redisTemplate.opsForValue().get(phone);
        if (!StringUtils.isEmpty(code)) {
            return AjaxResult.warn("短信已发送，请稍后再试");
        }

        // 校验手机号
        if (StringUtils.isEmpty(phone)) {
            return AjaxResult.error("手机号不能为空");
        }
        if (!PHONE_PATTERN.matcher(phone).matches()) {
            return AjaxResult.error("手机号码格式不正确");
        }
        String templateCode = getTemplateCodeByType(type);
        if (templateCode == null) {
            return AjaxResult.error("无效的验证码类型");
        }
        // 生成随机验证码并发送
        code = RandomUtils.getFourBitRandom();
        Map<String, Object> param = new HashMap<>();
        param.put("code", code);

        boolean isSend = send(param, phone,templateCode);
        if (isSend) {
            // 发送成功，把验证码放到redis里面
            redisTemplate.opsForValue().set(phone, code, 1, TimeUnit.MINUTES);
            return AjaxResult.success("验证码发送成功");
        } else {
            return AjaxResult.error("短信发送失败");
        }
    }

    // 发送短信
    public boolean send(Map<String, Object> map, String phone, String templateCode) {

        DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");

        String jsonCode = JSON.toJSONString(map);
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", jsonCode);

        try {
            CommonResponse response = client.getCommonResponse(request);
            if (response.getHttpResponse() != null && response.getHttpResponse().isSuccess()) {
                logger.info("短信发送成功");
                return true;
            } else {
                logger.error("短信发送失败，错误码：{}，错误消息：{}", response.getHttpResponse().getStatus(), response.getData());
                return false;
            }
        } catch (ClientException e) {
            logger.error("短信发送异常，错误消息：{}", e.getMessage(), e);
            return false;
        }
    }
    private String getTemplateCodeByType(String type) {
        switch (type) {
            case "login":
                return templateCodeLogin;
            case "register":
                return templateCodeRegister;
            case "resetPassword":
                return templateCodeResetPassword;
            case "changePhone":
                return templateCodeChangePhone;
            default:
                return null;
        }
    }
}
